;#
;# calc_cor_asm.S
;#
;# Calculate all correlations for prior the OL LTP
;# 
;# Oded Rosen, 2011   
;#

	.text
	.globl comp_corr
	
	.arm
	
;#************************************************************************
;#
;#  FUNCTION: comp_corr 
;#
;#  PURPOSE: Calculate all correlations of scal_sig[] in a given delay
;#           range.
;#
;#  DESCRIPTION:
;#      The correlation is given by
;#           cor[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
;#      The functions outputs the all correlations 
;#
;#************************************************************************/

	;# inputs:
	scal_sig	.req r0
	L_frame		.req r1
	lag_max		.req r2
	lag_min		.req r3
	
	;# local vars:
	p			.req r4
	i			.req r6
	i_times_2	.req r5
	j			.req r7
	t0			.req r8
	p_val		.req r9
	p_1_val		.req r10
	p_mac		.req r10
	p_mul		.req r11
	
	
	;# output array:
	corr		.req r12

comp_corr:
		;# scal_sig[],	i   : scaled signal
		;# L_frame,		i   : length of frame to compute pitch
		;# lag_max,		i   : maximum lag
		;# lag_min,		i   : minimum lag
		;# corr[],		o   : correlation of selected lag
		
		;# function has more than 4 arguments, 
		;# so the 5th argument is on the stack, get it:
		POP			{corr}
		;# Stack current values:
		PUSH		{r4-r11}			;# stack
		
		;# Outer loop pre:
		LSL			i,lag_max,#1		;# outer loop var "i" starts 
										;# with lag_max * 2
		LSL			lag_min,lag_min,#1	;# lag_min is also multiplied
o_loop:
		MOV			p,scal_sig
		MOV			t0,#0
		
		;# Inner loop pre:
		MOV			j,#0
i_loop:
		;# Inner loop:
		LDR			p_val,[p]			;# load next values into p_val, 
		LDR			p_1_val,[p,-i]		;#	and p_1_val.
		SMULBB 		p_mul,p_val,p_1_val	;# multiply 16x16 (r1,r2)
		SMULTT 		p_val,p_val,p_1_val	;# multiply 16x16 (r1,r2)
		QDADD		t0,t0,p_mul
		QDADD		t0,t0,p_val
		
i_loop_post:
		; # Inner loop post:
		ADD			j,j,#2
		ADD			p,p,#4
		CMP			j,L_frame
		BLT			i_loop
		
		LSL			i_times_2,i,#1			
		STR			t0,[corr,-i_times_2]
		
		;# Outer loop post:
		SUB			i,i,#2
		CMP			i,lag_min
		BGE			o_loop
		
		;# Unstack values and return:
		POP			{r4-r11}			;# unstack
		PUSH		{corr}
		BX			lr					;# return
